class Snake {
  //   el: HTMLElement;
  //   constructor() {
  //     this.el = document.querySelector(".stage > .snake")!;
  //   }
  // 获取一个表示蛇头的元素
  head: HTMLElement;
  // 蛇的身体(包括蛇头) 集合
  body: HTMLCollection;
  // 获取蛇的容器
  el: HTMLElement;
  constructor() {
    this.el = document.querySelector(".stage > .snake")!;
    this.head = document.querySelector(".stage > .snake > div") as HTMLElement;
    this.body = this.el.getElementsByTagName("div");
    // this.body = document.querySelectorAll(".snake");
  }
  // 获取蛇头坐标
  get X() {
    return this.head.offsetLeft;
  }
  get Y() {
    return this.head.offsetTop;
  }
  // 设置蛇头坐标
  set X(value: number) {
    // 如果新值 和 旧值 则直接返回不再修改
    if (this.X === value) {
      return;
    }
    // value 在 0 ~ 290 之间
    if (value < 0 || value > 290) {
      // 蛇已撞墙, 抛出异常
      throw new Error("蛇撞墙了");
    }
    /**
     * 修改X时,是在修改水平坐标,蛇向左移动,不能向右掉头,反之亦然
     * 怎么判断
     *  蛇头坐标 和 第二节的坐标重合时表示蛇在掉头
     */
    if (this.body[1] && (this.body[1] as HTMLElement).offsetLeft === value) {
      // throw new Error("蛇水平方向掉头")
      // 如果掉头了,让蛇向反方向继续移动
      // if (value > this.X) {
      //   // 如果新值value大于旧值X 则说明蛇在掉头
      //   value = this.X - 10;
      // }
      value = this.X + (value > this.X ? -10 : 10);
    }
    // 移动身体
    this.moveBody();

    this.head.style.left = value + "px";
    // 蛇头撞到蛇身
    this.checkHeadBody();
  }
  set Y(value: number) {
    if (this.Y === value) {
      return;
    }
    if (value < 0 || value > 290) {
      // 蛇已撞墙, 抛出异常
      throw new Error("蛇撞墙了");
    }
    // 掉头处理
    if (this.body[1] && (this.body[1] as HTMLElement).offsetTop === value) {
      value = this.Y + (value > this.Y ? -10 : 10);
    }
    // 移动身体
    this.moveBody();

    this.head.style.top = value + "px";
    // 蛇头撞到蛇身
    this.checkHeadBody();
  }
  // 蛇添加身体
  addBody() {
    // 向element 中添加一个div
    this.el.insertAdjacentHTML("beforeend", "<div></div>");
  }
  // 添加一个蛇身体的移动方法
  moveBody() {
    /**
     * 将后一节的身体设置为前一节身体的位置
     * 举例:  第四节 = 第三节的位置
     *        第三节 = 第二节的位置
     *        第二节 = 第一节的位置(蛇头)
     * 遍历蛇所有身体
     */
    for (let i = this.body.length - 1; i > 0; i--) {
      // if (i > 1) {
        // 获取前边身体的位置
        let X = (this.body[i - 1] as HTMLElement).offsetLeft;
        let Y = (this.body[i - 1] as HTMLElement).offsetTop;
        // 将值设置到当前身体上
        (this.body[i] as HTMLElement).style.left = X + "px";
        (this.body[i] as HTMLElement).style.top = Y + "px";
      // }
    }
  }
  // 检查蛇头是否和身体发生碰撞
  checkHeadBody() {
    // 发生碰撞蛇的长度至少为5 田形状还没有重合的
    if (this.body.length > 4) {
      for (let i = 0; i < this.body.length; i++) {
        let bodyItemEl = this.body[i] as HTMLElement;
        if (
          this.X === bodyItemEl.offsetLeft &&
          this.Y === bodyItemEl.offsetTop
        ) {
          throw new Error("蛇撞到了自己~~");
        }
      }
    }
  }
}
export default Snake;
